#include"wavapi.h"
typedef struct _RIFF_HEADER{
uint32_t RiffID;//'RIFF'
uint32_t RiffSize;//文件总长度-8
uint32_t RiffFormat;//类型'WAVE'
}RIFF_HEADER;
typedef struct _BLOCK_HEADER{
uint32_t BlockID;//'fmt ' 'fact' 'Data'
uint32_t BlockSize;//
}BLOCK_HEADER;
#define MAKETAG(a,b,c,d) ((a&0xff)|((b<<8)&(0xff00))|((c<<16)&(0xff0000))|((d<<24)&(0xff000000)))
//'abcd'
//0成功-1失败
int OpenWavFile(const char*filename,FILE_WAV*fileinfo,int bReadMode){
	if(bReadMode){
	   BLOCK_HEADER BlockHeader={0};
	   fileinfo->fp=fopen(filename,"rb");
	   if(fileinfo->fp==NULL){
		  return -1;
	   }else{
	      fileinfo->readmode=1;
	   }
//检查是否为wav文件	   
	   do{
		  RIFF_HEADER Riff_Header={0};
		  fread(&Riff_Header,1,sizeof(Riff_Header),fileinfo->fp);
		  if((Riff_Header.RiffID!=MAKETAG('R','I','F','F'))||
		     (Riff_Header.RiffFormat!=MAKETAG('W','A','V','E'))){
			 CloseWavFile(fileinfo);
			 return -1;
		  }
	   }while(0);
	   while(fread(&BlockHeader,1,sizeof(BlockHeader),fileinfo->fp)==sizeof(BlockHeader)){
//		printf("BlockID:%0.4s BlockSize:%u\n",(char*)&(BlockHeader.BlockID),BlockHeader.BlockSize);
//读取格式信息
        printf("ID:%4s Size:%u\n",(char*)&BlockHeader.BlockID,BlockHeader.BlockSize);
		if(BlockHeader.BlockID==MAKETAG('f','m','t',' ')){
		   uint32_t Pos=ftell(fileinfo->fp);
		   fread(&fileinfo->format,1,sizeof(WAVE_FORMAT),fileinfo->fp);
		   fseek(fileinfo->fp,Pos,SEEK_SET);
		}else
//定位数据未知和数据大小
		if(BlockHeader.BlockID==MAKETAG('d','a','t','a')){
		   fileinfo->total=BlockHeader.BlockSize;
		   break;
		}
		
		if(BlockHeader.BlockSize>0){
		   fseek(fileinfo->fp,BlockHeader.BlockSize,SEEK_CUR);
		}
	  }
	  if(fileinfo->total==0){
		 CloseWavFile(fileinfo);
		 return -1;
	  }
	  return 0;
	}else{
	   fileinfo->fp=fopen(filename,"wb");
	   if(fileinfo->fp==NULL){
		  return -1;
	   }else{
	      fileinfo->readmode=0;
		  fileinfo->total=0;
		  fileinfo->pos=0;
	   }
//写入WAV头	   
	   do{
		  RIFF_HEADER Riff_Header={MAKETAG('R','I','F','F'),0,MAKETAG('W','A','V','E')};
		  fwrite(&Riff_Header,1,sizeof(RIFF_HEADER),fileinfo->fp);
	   }while(0);
//写入格式
	   do{
		  BLOCK_HEADER BlockHeader={MAKETAG('f','m','t',' '),sizeof(WAVE_FORMAT)};
		  fwrite(&BlockHeader,1,sizeof(BLOCK_HEADER),fileinfo->fp);
		  fwrite(&fileinfo->format,1,sizeof(WAVE_FORMAT),fileinfo->fp);
	   }while(0);
//写入数据头
	   do{
		  BLOCK_HEADER BlockHeader={MAKETAG('d','a','t','a'),0};
		  fwrite(&BlockHeader,1,sizeof(BLOCK_HEADER),fileinfo->fp);
	   }while(0);		
	}
	return -1;
	
}
//返回读取的字节数
int ReadWavFile(FILE_WAV*fileinfo,char*buffer,uint32_t length){
	int ReadSize=fread(buffer,1,length,fileinfo->fp);
	fileinfo->pos+=ReadSize;
	return ReadSize;
}
//返回写入的字节数
int WriteWavFile(FILE_WAV*fileinfo,char*buffer,uint32_t length){
	int WriteSize=fwrite(buffer,1,length,fileinfo->fp);
	fileinfo->total+=WriteSize;
	return WriteSize;
}
int CloseWavFile(FILE_WAV*fileinfo){
	if(fileinfo->readmode==0){
	   uint32_t total=ftell(fileinfo->fp)-8;
	   fseek(fileinfo->fp,4,SEEK_SET);
	   fwrite(&total,1,4,fileinfo->fp);
	   //12+8+16+4
	   fseek(fileinfo->fp,40,SEEK_SET);
	   fwrite(&fileinfo->total,1,4,fileinfo->fp);
	}
	fclose(fileinfo->fp);
	return 0;
}
void ShowWavInfo(WAVE_FORMAT format,uint32_t total){
	printf("Channels:%hu Samples:%u Bits:%hu\n",
	format.nChannels,format.nSamplesPerSec,format.wBitsPerSample);
	if(total>0){
	   int perbytes=format.nChannels*format.nSamplesPerSec*format.wBitsPerSample/8;
	   if(perbytes>0){
		  int totaltime= total/perbytes;
		  printf("maybe can play:%02d:%02d:%02d\n",totaltime/3600,totaltime%3600/60,totaltime%60);
	   }
	}
}